package com.yu.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.stonehenge.backend.tools.StaticToolit;
import com.stonehenge.backend.tools.data.GeneratorSID;

/**
 * 小工具
 * @author FU, lingjin Administrator
 * @Date 2016年9月4日
 */
public class Toolkit {
    private static final Logger logger = LoggerFactory.getLogger(Toolkit.class);

    static Random rn = new Random();
    
    public static Map<String,Object> toMap(JSONObject jsonObject){
        HashMap<String, Object> data = Maps.newHashMap();  
        Set<String> it =  jsonObject.keySet();  
        // 遍历jsonObject数据，添加到Map对象  
        for(String key :it ) {  
            data.put(key, jsonObject.get(key));  
        }  
        return data;  
    }

    /**
     * 防止误差，输入输出是单位是分，整型
     * 如果返回是null，说明传入的参数出错了d
     * @param amount
     * @param n
     * @return
     */
    public static Integer[] resortLuckyMoney(int amount, int n) {
        
        if(amount<n)
            return null;
        amount = amount-n;
        Integer[] list = new Integer[n];
        
        Float[] w = new Float[n];
        float wMax = 0f;
        for (int i = 0; i < n; i++) {
            list[i] = 0;
            float w0 = rn.nextFloat() * rn.nextFloat() + 0.01f;
            if(rn.nextFloat()<0.05)
                w0 = rn.nextFloat()*0.01f/n+0.01f; 
            wMax += w0;
            w[i] = w0;
        }
        if (amount <= 1 || wMax < 0.01)
            list[rn.nextInt(n)] = amount;
        else {
            int total = 0;
            for (int i = 0; i < n; i++) {
                int testAmount = (int) (amount * w[i] / wMax);                               
                if (testAmount + total > amount) {
                    testAmount = amount - total;
                    list[i] = testAmount;
                    total += testAmount;
                    break;
                } else {
                    list[i] = testAmount;
                    total += testAmount;
                }
                if (i == n - 1) {
                    int diff = amount - total;
                    list[i] += diff;
                }
            }
        }

        for (int i = 0; i < list.length; i++) {
            list[i] += 1;
        }
        return list;
    }
    
    /**
     * 判定是否是手机号
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile) {
        if(StaticToolit.isEmpty(mobile))
            return false;
        //mobile=mobile.trim().replaceAll("\\s", "");
        if(mobile.length()!=11)
          return false;  
        return Pattern.matches("^1[3|4|5|6|7|8][\\d]{9}$", mobile);
    }
    
    /**
     * 精简的userid生成器
     * @param maxID
     * @param localIP
     * @param ipset
     * @return
     */    
    public static long newUserID(long maxID, String localIP, Set<String> ipset) {
        
        int ip = rn.nextInt(89) + 10;        
        int index = -1;
        if (!(localIP.isEmpty())){
            List<String> iplist = StaticToolit.convSet2List(ipset);
            index = iplist != null ? iplist.indexOf(localIP) : -1;
            if (index < 0)
                index = Math.abs(localIP.hashCode());            
            ip = index % 19;
        }

        long start = System.currentTimeMillis();
        long time = start - 1472526222000L;
        int timeInt = (int) (time % 43L);

        if (maxID <= 1L)
            maxID = Math.abs(GeneratorSID.getUUID().hashCode() % 1000);
        else
            maxID += 10000L;

        long rand = maxID * 19 + ip;
        rand = rand * 43L + timeInt + 2000000L;
        if (rand < 0L)
            return ((rand + Long.MAX_VALUE) % 1000000L + 1000000L);
        
        logger.info("localIP=" + localIP + " index=" + index);
        return rand;
    }

    public static int getWordCount(String s) {
        if (null == s) {
            return 0;
        }
        int length = 0;
        for(int i = 0; i < s.length(); i++) {
            int ascii = Character.codePointAt(s, i);
            if(ascii >= 0 && ascii <=255)
                length++;
            else
                length += 2;

        }
        return length;
    }


    public static String newGroupID(String consumeids,int mile){
        if(consumeids==null)
            return null;        
        List<String> consumeids_list = StaticToolit.string2List(consumeids, ",");
        Collections.sort(consumeids_list);
        String consumeids2= StaticToolit.list2String(consumeids_list, "-");
        return consumeids2+"_"+mile;        
    }

    
    public static boolean _isUTF8(byte[] rawtext) {
        int score = 0;
        int i, rawtextlen = 0;
        int goodbytes = 0, asciibytes = 0;
        // Maybe also use UTF8 Byte Order Mark: EF BB BF
        // Check to see if characters fit into acceptable ranges
        rawtextlen = rawtext.length;
        for (i = 0; i < rawtextlen; i++) {
         if ((rawtext[i] & (byte) 0x7F) == rawtext[i]) { 
          // 最高位是0的ASCII字符
          asciibytes++;
          // Ignore ASCII, can throw off count
         } else if (-64 <= rawtext[i] && rawtext[i] <= -33
           //-0x40~-0x21
           && // Two bytes
           i + 1 < rawtextlen && -128 <= rawtext[i + 1]
           && rawtext[i + 1] <= -65) {
          goodbytes += 2;
          i++;
         } else if (-32 <= rawtext[i]
           && rawtext[i] <= -17
           && // Three bytes
           i + 2 < rawtextlen && -128 <= rawtext[i + 1]
           && rawtext[i + 1] <= -65 && -128 <= rawtext[i + 2]
           && rawtext[i + 2] <= -65) {
          goodbytes += 3;
          i += 2;
         }
        }
        if (asciibytes == rawtextlen) {
         return false;
        }
        score = 100 * goodbytes / (rawtextlen - asciibytes);
        // If not above 98, reduce to zero to prevent coincidental matches
        // Allows for some (few) bad formed sequences
        if (score > 98) {
         return true;
        } else if (score > 95 && goodbytes > 30) {
         return true;
        } else {
         return false;
        }
    }
        
    
    static public String _filterOffUtf8Mb4(String text) throws UnsupportedEncodingException {  
        byte[] bytes = text.getBytes("UTF-8");  
        ByteBuffer buffer = ByteBuffer.allocate(bytes.length);  
        int i = 0;  
        while (i < bytes.length) {  
            short b = bytes[i];  
            if (b > 0) {  
                buffer.put(bytes[i++]);  
                continue;  
            }  
            b += 256;  
            if ((b ^ 0xC0) >> 4 == 0) {  
                buffer.put(bytes, i, 2);  
                i += 2;  
            }  
            else if ((b ^ 0xE0) >> 4 == 0) {  
                buffer.put(bytes, i, 3);  
                i += 3;  
            }  
            else if ((b ^ 0xF0) >> 4 == 0) {  
                i += 4;  
            }  
        }  
        buffer.flip();  
        return new String(buffer.array(), "utf-8");  
    }  
    
    @Deprecated
    public static String toMD5(String plainText) {
        try {
           //生成实现指定摘要算法的 MessageDigest 对象。
           MessageDigest md = MessageDigest.getInstance("MD5");  
           //使用指定的字节数组更新摘要。
           md.update(plainText.getBytes());
           //通过执行诸如填充之类的最终操作完成哈希计算。
           byte b[] = md.digest();
           //生成具体的md5密码到buf数组
           int i;
           StringBuffer buf = new StringBuffer("");
           for (int offset = 0; offset < b.length; offset++) {
             i = b[offset];
             if (i < 0)
               i += 256;
             if (i < 16)
               buf.append("0");
             buf.append(Integer.toHexString(i));
           }
           System.out.println("32位: " + buf.toString());// 32位的加密
           System.out.println("16位: " + buf.toString().substring(8, 24));// 16位的加密，其实就是32位加密后的截取
           return buf.toString();
        } 
        catch (Exception e) {
          e.printStackTrace();
        }
        return null;
    }
    
    
	/**
	 * 获取充值订单号
	 * @return
	 */
    public static String newTradeNo(){
    	StringBuffer tradeNo = new StringBuffer(String.valueOf(System.currentTimeMillis()));
    	//StringBuffer tradeNo = new StringBuffer(new SimpleDateFormat("ddHHmmss").format(new Date(System.currentTimeMillis())));
    	// 获得随机数  
    	double pross = (1 + new Random().nextDouble()) * Math.pow(10, 8);  
    	tradeNo.append(String.valueOf(pross).substring(8, 12))   ;  
    	return tradeNo.toString();
    }
    
    public static String getAlipayDateString(){
    	return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
    }
    
    private static Properties prop;
    private void init(){
    	try {
    		prop = new Properties();
    		InputStream in = this.getClass().getClassLoader().getResourceAsStream("level.properties");
    		prop.load(in);
	    } catch (IOException e) {   
	        e.printStackTrace();   
	    } 
    }
    
    public static Toolkit one = new Toolkit();
    /**
     * 从配置文件中level.properties ，根据等级key 获取相应的值 
     * @param key
     * @return
     */
    public int getLevelExpr(Object key){
    	if (prop == null){
    		try {
        		prop = new Properties();
        		InputStream in = this.getClass().getClassLoader().getResourceAsStream("level.properties");
        		prop.load(in);
    	    } catch (IOException e) {   
    	        e.printStackTrace();   
    	    } 
    	}
    	int result = Integer.valueOf(prop.getProperty("level"+key));
    	return result;
    }
    
    public int getMaxLimitExpr(){
    	if (prop == null){
    		try {
        		prop = new Properties();
        		InputStream in = this.getClass().getClassLoader().getResourceAsStream("level.properties");
        		prop.load(in);
    	    } catch (IOException e) {   
    	        e.printStackTrace();   
    	    } 
    	}
    	return Integer.valueOf(prop.getProperty("red_limit_expr"));
    }
    
    public BigDecimal newProfit(BigDecimal amount){
    	return amount.divide(new BigDecimal(100)).multiply(new BigDecimal(6+new Random().nextDouble() *2)) .setScale(2,   BigDecimal.ROUND_HALF_UP);
    }
    
    public static int randomkartcode(){
    	Calendar cal = Calendar.getInstance();
    	int first = cal.get(Calendar.SECOND) % 9;
    	int second = cal.get(Calendar.MINUTE) % 10;
    	int third = cal.get(Calendar.HOUR) % 10;
    	return first * 1000 + second * 100 + third * 10 +(int)(Math.random() * 10) ;
    }
    
    
    public static void main(String[] args) throws UnsupportedEncodingException {
    	System.out.println(Toolkit.newTradeNo());
//    	for(int i=0;i<30;i++){
//    		System.out.println(one.newProfit(new BigDecimal(100)));
//    	}
    	
    	/*
    	System.out.println(System.currentTimeMillis()/1000);
    	System.out.println(String.valueOf(System.currentTimeMillis()/1000).substring(2));
    	
    	/*
    	Map<String,Object> obj = Maps.newHashMap();
    	obj.put("prodid", 1);
    	obj.put("detailid", 1);
    	obj.put("productdetail", "sss");
    	obj.put("note", null);
    	obj.put("amount", 8.88);
    	obj.put("address", "广济南路270号");
    	obj.put("province", "江苏省");
    	obj.put("city", "苏州市");
    	obj.put("name", "王小二");
    	obj.put("mobile", 118121020);
    	obj.put("phone", 823923);
    	System.out.println(new JSONObject(obj));
    	System.out.println(Toolkit.one.getLevelExpr(2));
    	String pattern = "\\d{6,6}";
    	 
        // 创建 Pattern 对象
        Pattern r = Pattern.compile(pattern);
   
        // 现在创建 matcher 对象
        Matcher m = r.matcher("128903");
        System.out.println(m.find());
        System.out.println(newUserID(100000L, "10.10.10.1", ServerInfo.AllowIPs_Service));

        //System.out.println(newUserID(100000L, "10.10.10.1", ServerInfo.AllowIPs_Service));

        //System.out.println((-100L + Long.MAX_VALUE) % 1000000L);
        //System.out.println((-100L + -1) * 1000000L + 1000000L);
        //String emojiString2=new String("\ud83d\ude00\u2602");

        //System.out.println(_isUTF8("sff.235235".getBytes()));
        //System.out.println(_isUTF8("我".getBytes()));
        //System.out.println(_isUTF8("\u8776dd".getBytes()));
        //System.out.println(_isUTF8(emojiString2.getBytes()));
        
        
        //System.out.println(_filterOffUtf8Mb4("sff.235235"));
        //System.out.println(_filterOffUtf8Mb4("我"));
        //System.out.println(_filterOffUtf8Mb4("\u8776 dd"));
        //System.out.println(_filterOffUtf8Mb4(emojiString2));
        
//        System.out.println(hasEmoji("sff.235235"));
//        System.out.println(hasEmoji("我"));
//        System.out.println(hasEmoji("\u8776 dd"));
//        System.out.println(hasEmoji(emojiString2));
//        System.out.println("isMobile=" + isMobile("13601011234"));

        Integer[] resortLuckyMoney = resortLuckyMoney(100,8);

        int n=0;
        for (Integer integer : resortLuckyMoney) {
            n+=integer;            
        }
        System.out.println("lucky=" + Arrays.asList(resortLuckyMoney) + " total=" + n);
        */

    }
}


